# -*- coding: utf-8 -*-
import os

import socketio
from app.api.routers import agv
from app.common.exception.exception_handler import register_exception
from app.core.conf import ST
from app.database.db_sqlite import create_table
from app.middleware import register_middleware
from app.sche_task import schedulerIns
from app.sche_task.agv import register_agv_event
from app.sio_agv.agv_socket import AGV
from app.sio_web import sio
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi_pagination import add_pagination
from loguru import logger


def register_app():
    # FastAPI
    app = FastAPI(
        title=ST.TITLE,
        version=ST.VERSION,
        description=ST.DESCRIPTION,
        docs_url=None,
        # docs_url=None,
        redoc_url=ST.REDOCS_URL,
        openapi_url=ST.OPENAPI_URL,
    )

    if ST.STATIC_FILES:
        # 注册静态文件
        register_static_file(app)

    # 注册swagger ui
    register_docs(app)

    # 中间件
    register_middleware(app)
    #
    register_cros_middleware(app)

    # 路由
    register_router(app)

    # 分页
    register_page(app)
    # 初始化连接
    register_init(app)

    # 全局异常处理
    register_exception(app)
    # register socketio
    register_socketio(app)

    # start agv
    if ST.CONNECT_AGV:
        register_agv()

    # start scheduler task
    if ST.START_EVENT:
        register_scheduler()

    return app


def register_docs(app: FastAPI):
    @app.get("/", tags=["Docs"])
    def index():
        return RedirectResponse(ST.DOCS_URL)

    @app.get(ST.DOCS_URL, include_in_schema=False)
    async def custom_swagger_ui_html():
        return get_swagger_ui_html(
            openapi_url=app.openapi_url,
            title=app.title + " - Swagger UI ",
            oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
            swagger_js_url="/static/swagger-ui/swagger-ui-bundle.js",
            swagger_css_url="/static/swagger-ui/swagger-ui.css",
            swagger_favicon_url="/static/swagger-ui/favicon.png",
        )


def register_router(app: FastAPI):
    """
    路由

    :param app: FastAPI
    :return:
    """
    app.include_router(agv)


def register_static_file(app: FastAPI):
    """
    静态文件交互开发模式, 生产使用 nginx 静态资源服务

    :param app:
    :return:
    """

    if not os.path.exists("./static"):
        os.mkdir("./static")
    app.mount("/static", StaticFiles(directory="static"), name="static")


def register_init(app: FastAPI):
    """
    初始化连接

    :param app: FastAPI
    :return:
    """

    @app.on_event("startup")
    async def startup_event():
        # 创建数据库表
        await create_table()
        #  连接redis

        # if settings.REDIS_OPEN:
        #     # 连接redis
        #     await redis_client.init_redis_connect()

    @app.on_event("shutdown")
    async def shutdown_event():
        pass
        # if settings.REDIS_OPEN:
        #     # 关闭redis连接
        #     await redis_client.close()


def register_page(app: FastAPI):
    """
    分页查询

    :param app:
    :return:
    """
    add_pagination(app)


def register_socketio(app: FastAPI):
    """注册 socket io
    Args:
        app (FastAPI): _description_
    """
    app.mount("/ws", socketio.ASGIApp(sio))


def register_cros_middleware(app: FastAPI):
    app.add_middleware(
        CORSMiddleware,
        # 允许跨域的源列表，例如 ["http://www.example.org"] 等等， ["*"] 表示允许任何源
        allow_origins=["*"],
        # 跨域请求是否支持 cookie，默认是 False，如果为 True，allow_origins 必须为具体的源，不可以是 ["*"]
        allow_credentials=False,
        # 允许跨域请求的 HTTP 方法列表，默认是 ["GET"]
        allow_methods=["*"],
        # 允许跨域请求的 HTTP 请求头列表，默认是 []，可以使用 ["*"] 表示允许所有的请求头
        # 当然 Accept、Accept-Language、Content-Language 以及 Content-Type 总之被允许的
        allow_headers=["*"],
    )


def register_scheduler():
    """启动定时任务计划
    Args:
        app (FastAPI): _description_
    """
    register_agv_event()
    # schedulerIns.start()


def register_agv():
    # 如果5G网络不畅通,则返回
    # if AGV.ping_agv(ST.AGV1_IP):
    #     AGV.get_agv(ST.AGV1_IP, ST.AGV_PORT)
    #     logger.debug(ST.AGV1_IP, "ZTX AGV1连接成功")
    # if AGV.ping_agv(ST.AGV2_IP):
    #     AGV.get_agv(ST.AGV2_IP, ST.AGV_PORT)
    #     logger.debug(ST.AGV2_IP, "ZTX AGV2连接成功")
    # if AGV.ping_agv(ST.AGV3_IP):
    #     AGV.get_agv(ST.AGV3_IP, ST.AGV_PORT)
    #     logger.debug(ST.AGV1_IP, "ZTX AGV3连接成功")
    # if AGV.ping_agv(ST.AGV4_IP):
    #     AGV.get_agv(ST.AGV4_IP, ST.AGV_PORT)
    #     logger.debug(ST.AGV4_IP, "fork agv 连接成功")
    if AGV.ping_agv(ST.AGV5_IP):
        AGV.get_agv(ST.AGV5_IP, ST.AGV_PORT)
        logger.debug(ST.AGV5_IP, "nav agv连接成功")
